package vn.nt.healthcare.server.ws.service.impl;

import java.util.Date;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import vn.nt.healthcare.server.ws.domain.Company;
import vn.nt.healthcare.server.ws.model.Push;
import vn.nt.healthcare.server.ws.model.TimeSpecial;
import vn.nt.healthcare.server.ws.repositories.CompanyRepository;
import vn.nt.healthcare.server.ws.service.PushService;
import vn.nt.healthcare.server.ws.util.Constants;

@Service("pushService")
@Transactional
public class PushServiceImpl implements PushService {

	@Autowired
	private CompanyRepository companyRepository;

	@SuppressWarnings("unchecked")
	@Override
	public Object[] findAllPush(String companyId) {
		// TODO Auto-generated method stub
		Company company = companyRepository.findByCode(companyId);
		if (company != null) {
			Session session = null;
			Object[] results = new Object[2];
			try {
				session = ServiceHelper.openSession(company);
				StringBuilder sql = new StringBuilder(
						"SELECT DISTINCT p.token FROM Push p WHERE 1 =1 ");
				sql.append(" AND LOWER(p.os) = LOWER(:os)");
				String iosSql = sql.toString();
				Query query = session.createQuery(iosSql);
				query.setString("os", Constants.IOS);
				List<String> devicesIOS = query.list();
				results[0] = devicesIOS;
				String androidSql = sql.toString();
				query = session.createQuery(androidSql);
				query.setString("os", Constants.ANDROID);
				List<String> deviceAndroids = query.list();
				results[1] = deviceAndroids;
				return results;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				ServiceHelper.closeSession(session);
			}
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Object[] findPushesByDoctor(String companyId, int staffId,
			Date fromDate, Date toDate) {
		Company company = companyRepository.findByCode(companyId);
		if (company != null) {
			Session session = null;
			try {
				Object[] results = new Object[2];
				session = ServiceHelper.openSession(company);
				StringBuilder sql = new StringBuilder(
						"SELECT DISTINCT p.token FROM push_token p LEFT JOIN schedule s ON s.customerID = p.customerId  WHERE 1 =1 ");
				if (staffId > -1) {
					sql.append(" AND s.staffID = :staffId");
				}
				sql.append(" AND s.start_time >= :fromDate");
				sql.append(" AND s.start_time <= :endDate");
				sql.append(" AND LOWER(p.os) = LOWER(:os)");
				sql.append(" ORDER BY s.start_time desc");
				String sqlIOS = sql.toString();
				Query query = session.createQuery(sqlIOS);
				if (staffId > -1)
					query.setInteger("staffId", staffId);
				query.setTimestamp("fromDate", fromDate);
				query.setTimestamp("toDate", toDate);
				query.setString("os", Constants.IOS);
				List<String> listDevicesIOS = query.list();
				results[0] = listDevicesIOS;
				String sqlAndroid = sql.toString();
				query = session.createQuery(sqlAndroid);
				if (staffId > -1)
					query.setInteger("staffId", staffId);
				query.setTimestamp("fromDate", fromDate);
				query.setTimestamp("toDate", toDate);
				query.setString("os", Constants.IOS);
				List<String> listDevicesAndroid = query.list();
				results[1] = listDevicesAndroid;
				return results;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				ServiceHelper.closeSession(session);
			}
		}
		return null;
	}

	@Override
	public boolean registerPushFunction(String companyId, String token,
			String os, int customerId) {
		// TODO Auto-generated method stub
		Company company = companyRepository.findByCode(companyId);
		if (company != null) {
			Session session = null;
			Transaction transaction = null;
			try {
				session = ServiceHelper.openSession(company);
				transaction = session.beginTransaction();
				Push push = new Push();
				push.setToken(token);
				push.setOs(os);
				push.setCustomerId(customerId);
				push.setCreatedDate(new Date());
				session.saveOrUpdate(push);
				transaction.commit();
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
				if (transaction != null) {
					transaction.rollback();
				}
			} finally {
				ServiceHelper.closeSession(session);
			}
		}
		return false;
	}

	@Override
	public boolean destroyPushFunction(String companyId, int id) {
		// TODO Auto-generated method stub
		Company company = companyRepository.findByCode(companyId);
		if (company != null) {
			Session session = null;
			Transaction transaction = null;
			try {
				session = ServiceHelper.openSession(company);
				transaction = session.beginTransaction();
				Push push = (Push) session.get(Push.class, id);
				session.delete(push);
				transaction.commit();
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
				if (transaction != null) {
					transaction.rollback();
				}
			} finally {
				ServiceHelper.closeSession(session);
			}
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Object[] findPushesBySpecialTime(String companyId, int id) {
		// TODO Auto-generated method stub
		Company company = companyRepository.findByCode(companyId);
		if (company != null) {
			Session session = null;
			try {
				Object[] results = new Object[3];
				session = ServiceHelper.openSession(company);
				TimeSpecial time = (TimeSpecial) session.get(TimeSpecial.class,
						id);
				if (time == null) {
					return null;
				}
				StringBuilder sql = new StringBuilder(
						"SELECT distinct p.token from push_token left join pregnant pr on pr.customer_id = p.customerId WHERE 1 = 1");
				sql.append(" AND DATEDIFF(pr.female_date, NOW() ) BETWEEN :fromDate AND :toDate");
				sql.append(" AND LOWER(p.os) = LOWER(:os)");
				String sqlIOS = sql.toString();
				Query query = session.createQuery(sqlIOS);
				query.setString("os", Constants.IOS);
				query.setInteger("fromDate", time.getFromDate());
				query.setInteger("toDate", time.getToDate());
				List<String> listDevicesIOS = query.list();

				String sqlA = sql.toString();
				query = session.createQuery(sqlA);
				query.setString("os", Constants.ANDROID);
				query.setInteger("fromDate", time.getFromDate());
				query.setInteger("toDate", time.getToDate());
				List<String> listDevicesAndroid = query.list();

				String timeContent = time.getContent();
				results[0] = listDevicesIOS;
				results[1] = listDevicesAndroid;
				results[2] = timeContent;
				return results;
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			} finally {
				ServiceHelper.closeSession(session);
			}
		}
		return null;
	}

}
